package com.mt.restaurant.service.material.impl;

import com.mt.restaurant.dao.material.SupplierDao;

import com.mt.common.core.exception.BusinessException;
import com.mt.common.core.web.base.PageDTO;
import com.mt.common.core.web.base.PageResultDTO;
import com.mt.common.core.web.base.BaseEntity;
import com.mt.common.core.web.BaseService;
import com.mt.restaurant.service.material.SupplyMaterialService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.mt.restaurant.entity.material.Supplier;
import com.mt.restaurant.service.material.SupplierService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
@Transactional
public class SupplierServiceBean extends BaseService implements SupplierService {

    private static Logger logger = LogManager.getLogger();

    @Autowired
    private SupplierDao supplierDao;

    @Resource
    private RedisTemplate<String, List<Supplier>> redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    SupplyMaterialService supplyMaterialService;

    /**
     * 根据分页参数查询供应商集合
     *
     * @param pageDTO 分页条件
     */
    @Override
    public PageResultDTO findSuppliers(PageDTO pageDTO) {
        pageDTO.setStartIndex((pageDTO.getCurrentPage() - 1) * pageDTO.getPageSize());
        //TODO:请在此校验参数的合法性
        this.validateFindSuppliers(pageDTO);
        List<Supplier> supplierDTOS = this.supplierDao.findSuppliers(pageDTO);
        Long totalCount = this.supplierDao.findSupplierTotalCount(pageDTO);

        PageResultDTO pageResultDTO = new PageResultDTO();
        pageResultDTO.setTotalCount(totalCount);
        pageResultDTO.setDatas(supplierDTOS);

        return pageResultDTO;
    }

    /**
     * 查询全部供应商集合
     */
    @Override
    public List<Supplier> findAllSuppliers() {
        return this.supplierDao.findAllSuppliers();
    }

    /**
     * 查询所有供应商集合(只提取ID 和 Name)
     */
    @Override
    public List<Supplier> findAllSuppliersWithIdName() {
        //TODO:请在此校验参数的合法性
        this.validateFindAllSuppliersWithIdName();
        return this.supplierDao.findAllSuppliersWithIdName();
    }

    /**
     * 根据名称查询供应商集合(只提取ID 和 Name)
     *
     * @param supplierName 名称
     */
    @Override
    public List<Supplier> findSuppliersWithIdNameByName(String supplierName) {
        //TODO:请在此校验参数的合法性
        this.validateFindSuppliersWithIdNameByName(supplierName);
        //TODO:缓存取对应参数
        Set<String> keys = stringRedisTemplate.keys("searchData:Supplier_where_supplierName_" + supplierName);
        List<Supplier> suppliers = new ArrayList<>();
        if (keys.isEmpty()) {
            suppliers = this.supplierDao.findSuppliersWithIdNameByName(supplierName);
            redisTemplate.opsForValue().set("searchData:Supplier_where_supplierName_" + supplierName, suppliers, 30, TimeUnit.DAYS);
        } else {
            suppliers = redisTemplate.opsForValue().get("searchData:Supplier_where_supplierName_" + supplierName);
        }
        return suppliers;
    }

    /**
     * 根据ID查询指定的供应商(只提取ID 和 Name)
     *
     * @param supplierId Id
     */
    @Override
    public Supplier findSuppliersWithIdNameById(Long supplierId) {
        //TODO:请在此校验参数的合法性
        this.validateFindSuppliersWithIdNameById(supplierId);
        return this.supplierDao.findSuppliersWithIdNameById(supplierId);
    }

    /**
     * 根据ID查询指定的供应商
     *
     * @param supplierId Id
     */
    @Override
    public Supplier findSupplier(Long supplierId) {
        //TODO:请在此校验参数的合法性
        this.validateFindSupplier(supplierId);
        return this.supplierDao.findSupplier(supplierId);
    }

    /**
     * 根据ID查询指定的供应商(包含外键)
     *
     * @param supplierId Id
     */
    @Override
    public Supplier findSupplierWithForeignName(Long supplierId) {
        //TODO:请在此校验参数的合法性
        this.validateFindSupplierWithForeignName(supplierId);
        return this.supplierDao.findSupplierWithForeignName(supplierId);
    }

    /**
     * 新增供应商
     *
     * @param supplier 实体对象
     */
    @Override
    public Supplier saveSupplier(Supplier supplier) {
        //TODO:请在此校验参数的合法性
        this.validateSaveSupplier(supplier);
        //TODO:填充公共参数
        this.setSavePulicColumns(supplier);
        Long rows = this.supplierDao.saveSupplier(supplier);
        if (rows != 1) {
            String error = "新增保存供应商出错，数据库应该返回1,但返回了 " + rows;
            throw new BusinessException(error);
        }
        return supplier;
    }

    /**
     * 更新供应商
     *
     * @param supplier 实体对象
     */
    @Override
    public Supplier updateSupplier(Supplier supplier) {
        //TODO:请在此校验参数的合法性
        this.validateUpdateSupplier(supplier);
        Long rows = this.supplierDao.updateSupplier(supplier);
        if (rows != 1) {
            String error = "修改保存供应商出错，数据库应该返回1,但返回了 " + rows + ",数据可能被删除";
            throw new BusinessException(error);
        }
        try {
            supplier.setSupplyMaterialList(this.supplyMaterialService.changeSupplyMateialById(supplier.getEid(), supplier.getSupplyMaterialList()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return supplier;
    }

    /**
     * 根据ID删除供应商
     *
     * @param supplierId ID
     */
    @Override
    public void deleteSupplier(Long supplierId) {
        //TODO:请在此校验参数的合法性
        this.validateDeleteSupplier(supplierId);

        Map<Class<? extends BaseEntity>, EntityUsage> entityUsageMap = this.checkForeignEntity(Supplier.class, supplierId);
        if (entityUsageMap != null && entityUsageMap.size() > 0) {
            StringBuilder errors = new StringBuilder();
            errors.append("计划删除的数据正在被以下数引用\n");
            for (EntityUsage entityUsage : entityUsageMap.values()) {
                errors.append("\t").append(entityUsage.getEntityLabel()).append("\n");
                for (Map.Entry<Long, String> entry : entityUsage.getUsageIdNames().entrySet()) {
                    errors.append("\t\t").append(entry.getKey()).append("\t").append(entry.getValue()).append("\n");
                }
            }
            errors.append("，不能删除，请检查处理后再删除");
            throw new BusinessException(errors.toString());
        }

        Long rows = this.supplierDao.deleteSupplier(supplierId);
        if (rows != 1) {
            String error = "删除供应商出错，数据可能已经被删除";
            throw new BusinessException(error);
        }
    }

    //TODO:---------------验证-------------------

    private void validateFindSuppliers(PageDTO pageDTO) {
        //TODO:请使用下面方法添加数据过滤条件
        //		pageDTO.addFilter("creatorId",this.getLoginUserId());
        //TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateSupplier()写法
    }

    private void validateFindSuppliersWithIdNameByName(String supplierName) {
        //TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateSupplier()写法
    }


    private void validateFindAllSuppliersWithIdName() {
        //TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateSupplier()写法
    }

    private void validateFindSuppliersWithIdNameById(Long supplierId) {
        //TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateSupplier()写法
    }

    private void validateFindSupplier(Long supplierId) {
        //TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateSupplier()写法
    }

    private void validateFindSupplierWithForeignName(Long supplierId) {
        //TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateSupplier()写法
    }

    private void validateSaveSupplier(Supplier supplier) {
        //不为空判断
        if (supplier.getEid() != null || supplier.getCreatorId() != null || supplier.getCreateDatetime() != null) {
            throw new BusinessException("非法请求");
        }
        //TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateSupplier()写法
    }

    private void validateUpdateSupplier(Supplier supplier) {
        //不为空判断
        if (supplier.getEid() == null) {
            throw new BusinessException("唯一标识不能为空");
        }
        //是否存在判断
        if (this.supplierDao.findSupplierTotalCount(PageDTO.create(Supplier.FIELD_ID, supplier.getEid())) == 0) {
            throw new BusinessException("修改的供应商 " + supplier.getName() + " 不存在，修改失败，请重试或联系管理员");
        }
        //TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateSupplier()写法
    }

    private void validateDeleteSupplier(Long supplierId) {
        //TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateSupplier()写法
    }

    @Override
    public boolean canDownloadAttachment(String formName, Long id) {
        return true;
    }
}
